/*
 * Tabela Hash
 * 
 * Essa classe ajuda a obter desempenho no momento em que deverá ser verificado
 * todos os epitopos em comum de cada site.
 */
package epibot.testeProteinas;

import epibot.EstruturasBiologicas.Epitopo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;

/**
 *
 * @author Rafael
 */
public class TabelaHash {
    
    private static ListaEpitopoGeral lepg;

    /**
     * Vetor de indice e lista de epitopo para a tabela hash
     */
    private ArrayList<ArrayList<ListaEpitopoGeral>> tabela;
    /**
     * Armazena o tamanho da tabela hash
     */
    private int tamanho = 0;

    /**
     * Construtor Inicia a todos os campos de indice da tabela
     */
    public TabelaHash() {
        this.tabela = new ArrayList<ArrayList<ListaEpitopoGeral>>();
        this.tamanho = 10000; // quantidade de indices da tabela
        for (int i = 0; i < this.tamanho; i++) {
            ArrayList<ListaEpitopoGeral> lista = new ArrayList<ListaEpitopoGeral>();
            tabela.add(lista);
        }
    }

    /**
     * Retorna toda a tabela hash em uma lista de EpitoposGeral
     *
     * @return Tabela hash
     */
    public ArrayList<EpitopoGeral> getListaDeEpitopos() {
        ArrayList<EpitopoGeral> lista = new ArrayList<EpitopoGeral>();
        for (int i = 0; i < tamanho; i++) {
            for (int j = 0; j < tabela.get(i).size(); j++) {
                lista.add(tabela.get(i).get(j).getEpitopoGeral());
            }
        }
        return lista;
    }

    /**
     * Adiciona topo os epitopos na tabela
     *
     * @param epitopo Pbjeto do tipo Epitopo
     */
    public void adicionaEpitopos(Epitopo epitopo) {
        int indice = this.calculaIndiceDaTabela(epitopo.getNomeEpitopo());

        ListaEpitopoGeral listaEpG = this.buscaEpitopoGeral(epitopo.getNomeEpitopo(), indice);

        if (listaEpG != null) { //já existe um epitopo cadastrado
            listaEpG.add(epitopo);

        } else { // não existe epitopo cadastrado
            lepg = new ListaEpitopoGeral();
            lepg.add(epitopo);
            this.tabela.get(indice).add(lepg);
        }
    }

    /**
     * Busca um objeto epitopo geral a partir do nome do epitopo e um indice
     * 
     * @param nomeEpitopo Nome do epitopo
     * @param indice Indice
     * @return Lista com todos os epitoos
     */
    private ListaEpitopoGeral buscaEpitopoGeral(String nomeEpitopo, int indice) {

        ArrayList<ListaEpitopoGeral> lista = this.tabela.get(indice);

        for (Iterator iterator = lista.iterator(); iterator.hasNext();) {
            ListaEpitopoGeral ep = (ListaEpitopoGeral) iterator.next();
            if (ep.getNomeEpitopo().equals(nomeEpitopo)) {
                return ep;
            }
        }
        return null;
    }

    /**
     * Calcula o indice da tabela a partir no nome do epitopo
     *
     * @param nome Nome
     * @return Código de espalhamento
     */
    private int calculaIndiceDaTabela(String nome) {
        int codigoDeEspalhamento = this.calculaCodigoDaPalavra(nome);
        codigoDeEspalhamento = Math.abs(codigoDeEspalhamento);
        return codigoDeEspalhamento % tabela.size();
    }

    /**
     * Obtem um valor a partir da string informada
     *
     * @param palavra Palavra
     * @return Codigo
     */
    private int calculaCodigoDaPalavra(String palavra) {
        int codigo = 1;
        for (int i = 0; i < palavra.length(); i++) {
            codigo = 31 * codigo + palavra.charAt(i);
        }
        return codigo;
    }
}
